import React from "react";

export default class LearnEvent2 extends React.Component {
  constructor() {
    super();

    /**
     * 我们可以在constructor里面使用this改变add指向
     * 这种方式不方便传参 不推荐使用
     */
    // this.handle = this.handle.bind(this)
  }

  num = 1;
  name = "张三";

  // handle() {
  //   console.log("触发点击事件", this);
  // }

  /**
   * 由于handle函数使用箭头函数定义
   * 那么该函数的this就指向当前上下文
   * 也就是当前组件的实例
   *
   * 注意： 这种写法 无法进行传参 一般不推荐使用
   */
  handle = () => {
    console.log("触发了", this);
  };

  render() {
    /**
     * 在render函数里面this指向当前组件实例
     * 也就是当前这个类 所以我们可以直接在render里面使用this.xx
     * 获取这个类里面的方法或者属性
     */

    console.log(this);
    return (
      <div>
        <div>{this.name}</div>
        {/* 
          这里我们可以通过this获取到当前组件的方法
          我们知道函数的this是由调用的上下文决定的
          当前handle的上下文为window 有jsx经babel编译后
          会开启严格模式，所以this指向 了undefined
        */}
        <button onClick={this.handle}>点我</button>
        {/* 
          我们尅通过bind函数来改变this指向
          让函数内部指向当前组件实例
          并可以传递参数（有点依赖注入的意思）
        */}
        <button onClick={this.handle.bind(this)}>bin改变this</button>
        {/* 
          render函数的this指向当前实例
          所以，我们可以直接在绑定的时候使用箭头函数
          此时handle内部的this就会指向这个箭头函数
          那么箭头函数的this，又指向当前上下文，那么最终指向当前组件实例

          注意：
          使用箭头函数这种形式要在箭头函数里面调用对应的方法
          本上来说，事件触发的是箭头函数 
          然后箭头函数里面在触发对应的事件方法
          本质上来说，箭头函数是构造函数的语法糖，所以说每次创建都会new一下啊
          创建一个新的，每次render都会new一次，所以说可能有一点点的性能问题
          但是这种性能问题可以忽略不计
        */}
        <button onClick={() => this.handle()}>箭头函数</button>

        <button onClick={this.handle}>点我2</button>

        {/* 
          如果我们直接在事件后面调用方法，那么每次render后都会执行这个方法
          如果方法里面有些可以触发视图重新渲染的操作 会造成死循环

          一下是错误的示范

        */}
        {/* <button onClick={this.handle()}>点我2</button> */}
      </div>
    );
  }
}
